<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html class="pageview"><head>







<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<!-- base -->
<style type="text/css">
  

/* default css */

table {
  font-size: 1em;
  line-height: inherit;
  border-collapse: collapse;
}


tr {
  
  text-align: left;
  
}


div, address, ol, ul, li, option, select {
  margin-top: 0px;
  margin-bottom: 0px;
}

p {
  margin: 0px;
}


pre {
  font-family: Courier New;
  white-space: pre-wrap;
  margin:0;
}

body {
  margin: 6px;
  padding: 0px;
  font-family: Verdana, sans-serif;
  font-size: 10pt;
  background-color: #ffffff;
}


img {
  -moz-force-broken-image-icon: 1;
}

@media screen {
  html.pageview {
    background-color: #f3f3f3 !important;
    overflow-x: hidden;
    overflow-y: scroll;
  }

  

  body {
    min-height: 1100px;
    
    counter-reset: __goog_page__;
  }
  * html body {
    height: 1100px;
  }
  .pageview body {
    border-top: 1px solid #ccc;
    border-left: 1px solid #ccc;
    border-right: 2px solid #bbb;
    border-bottom: 2px solid #bbb;
    width: 648px !important;
    margin: 15px auto 25px;
    padding: 40px 50px;
  }
  /* IE6 */
  * html {
    overflow-y: scroll;
  }
  * html.pageview body {
    overflow-x: auto;
  }
  /* Prevent repaint errors when scrolling in Safari. This "Star-7" css hack
     targets Safari 3.1, but not WebKit nightlies and presumably Safari 4.
     That's OK because this bug is fixed in WebKit nightlies/Safari 4 :-). */
  html*#wys_frame::before {
    content: '\A0';
    position: fixed;
    overflow: hidden;
    width: 0;
    height: 0;
    top: 0;
    left: 0;
  }
  
  

  
    .writely-callout-data {
      display: none;
      *display: inline-block;
      *width: 0;
      *height: 0;
      *overflow: hidden;
    }
    .writely-footnote-marker {
      background-image: url('MISSING');
      background-color: transparent;
      background-repeat: no-repeat;
      width: 7px;
      overflow: hidden;
      height: 16px;
      vertical-align: top;

      
      -moz-user-select: none;
    }
    .editor .writely-footnote-marker {
      cursor: move;
    }
    .writely-footnote-marker-highlight {
      background-position: -15px 0;
      -moz-user-select: text;
    }
    .writely-footnote-hide-selection ::-moz-selection, .writely-footnote-hide-selection::-moz-selection {
      background: transparent;
    }
    .writely-footnote-hide-selection ::selection, .writely-footnote-hide-selection::selection {
      background: transparent;
    }
    .writely-footnote-hide-selection {
      cursor: move;
    }

    
    .editor .writely-comment-yellow {
      background-color: #FF9;
      background-position: -240px 0;
    }
    .editor .writely-comment-yellow-hover {
      background-color: #FF0;
      background-position: -224px 0;
    }
    .editor .writely-comment-blue {
      background-color: #C0D3FF;
      background-position: -16px 0;
    }
    .editor .writely-comment-blue-hover {
      background-color: #6292FE;
      background-position: 0 0;
    }
    .editor .writely-comment-orange {
      background-color: #FFDEAD;
      background-position: -80px 0;
    }
    .editor .writely-comment-orange-hover {
      background-color: #F90;
      background-position: -64px 0;
    }
    .editor .writely-comment-green {
      background-color: #99FBB3;
      background-position: -48px 0;
    }
    .editor .writely-comment-green-hover {
      background-color: #00F442;
      background-position: -32px 0;
    }
    .editor .writely-comment-cyan {
      background-color: #CFF;
      background-position: -208px 0;
    }
    .editor .writely-comment-cyan-hover {
      background-color: #0FF;
      background-position: -192px 0;
    }
    .editor .writely-comment-purple {
      background-color: #EBCCFF;
      background-position: -144px 0;
    }
    .editor .writely-comment-purple-hover {
      background-color: #90F;
      background-position: -128px 0;
    }
    .editor .writely-comment-magenta {
      background-color: #FCF;
      background-position: -112px 0;
    }
    .editor .writely-comment-magenta-hover {
      background-color: #F0F;
      background-position: -96px 0;
    }
    .editor .writely-comment-red {
      background-color: #FFCACA;
      background-position: -176px 0;
    }
    .editor .writely-comment-red-hover {
      background-color: #FF7A7A;
      background-position: -160px 0;
    }

    .editor .writely-comment-marker {
      background-image: url('MISSING');
      background-color: transparent;
      padding-right: 11px;
      background-repeat: no-repeat;
      width: 16px;
      height: 16px;
      -moz-user-select: none;
    }

    .editor .writely-comment-hidden {
      padding: 0;
      background: none;
    }
    .editor .writely-comment-marker-hidden {
      background: none;
      padding: 0;
      width: 0;
    }
    .editor .writely-comment-none {
      opacity: .2;
      filter:progid:DXImageTransform.Microsoft.Alpha(opacity=20);
      -moz-opacity: .2;
    }
    .editor .writely-comment-none-hover {
      opacity: .2;
      filter:progid:DXImageTransform.Microsoft.Alpha(opacity=20);
      -moz-opacity: .2;
    }
  


  
  .br_fix span+br:not(:-moz-last-node) {
    
    position:relative;
    
    left: -1ex
    
  }

  
  #cb-p-tgt {
    font-size: 8pt;
    padding: .4em;
    background-color: #ddd;
    color: #333;
  }
  #cb-p-tgt-can {
    text-decoration: underline;
    color: #36c;
    font-weight: bold;
    margin-left: 2em;
  }
  #cb-p-tgt .spin {
    width: 16px;
    height: 16px;
    background: url(//ssl.gstatic.com/docs/clipboard/spin_16o.gif) no-repeat;
  }
}

h6 { font-size: 8pt }
h5 { font-size: 8pt }
h4 { font-size: 10pt }
h3 { font-size: 12pt }
h2 { font-size: 14pt }
h1 { font-size: 18pt }

blockquote {padding: 10px; border: 1px #DDD dashed }

.webkit-indent-blockquote { border: none; }

a img {border: 0}

.pb {
  border-width: 0;
  page-break-after: always;
  /* We don't want this to be resizeable, so enforce a width and height
     using !important */
  height: 1px !important;
  width: 100% !important;
}

.editor .pb {
  border-top: 1px dashed #C0C0C0;
  border-bottom: 1px dashed #C0C0C0;
}

div.google_header, div.google_footer {
  position: relative;
  margin-top: 1em;
  margin-bottom: 1em;
}


/* Table of contents */
.editor div.writely-toc {
  background-color: #f3f3f3;
  border: 1px solid #ccc;
}
.writely-toc > ol {
  padding-left: 3em;
  font-weight: bold;
}
ol.writely-toc-subheading {
  padding-left: 1em;
  font-weight: normal;
}
/* IE6 only */
* html writely-toc ol {
  list-style-position: inside;
}
.writely-toc-none {
  list-style-type: none;
}
.writely-toc-decimal {
  list-style-type: decimal;
}
.writely-toc-upper-alpha {
  list-style-type: upper-alpha;
}
.writely-toc-lower-alpha {
  list-style-type: lower-alpha;
}
.writely-toc-upper-roman {
  list-style-type: upper-roman;
}
.writely-toc-lower-roman {
  list-style-type: lower-roman;
}
.writely-toc-disc {
  list-style-type: disc;
}

/* Ordered lists converted to numbered lists can preserve ordered types, and
   vice versa. This is confusing, so disallow it */
ul[type="i"], ul[type="I"], ul[type="1"], ul[type="a"], ul[type="A"] {
  list-style-type: disc;
}

ol[type="disc"], ol[type="circle"], ol[type="square"] {
  list-style-type: decimal;
}

/* end default css */


  /* default print css */
  
  @media print {
    body {
      padding: 0;
      margin: 0;
    }

    div.google_header, div.google_footer {
      display: block;
      min-height: 0;
      border: none;
    }

    div.google_header {
      flow: static(header);
    }

    /* used to insert page numbers */
    div.google_header::before, div.google_footer::before {
      position: absolute;
      top: 0;
    }

    div.google_footer {
      flow: static(footer);
    }

    /* always consider this element at the start of the doc */
    div#google_footer {
      flow: static(footer, start);
    }

    span.google_pagenumber {
      content: counter(page);
    }

    span.google_pagecount {
      content: counter(pages);
    }

    .endnotes {
      page: endnote;
    }

    /* MLA specifies that endnotes title should be 1" margin from the top of the page. */
    @page endnote {
      margin-top: 1in;
    }

    callout.google_footnote {
      
      display: prince-footnote;
      footnote-style-position: inside;
      /* These styles keep the footnote from taking on the style of the text
         surrounding the footnote marker. They can be overridden in the
         document CSS. */
      color: #000;
      font-family: Verdana;
      font-size: 10.0pt;
      font-weight: normal;
    }

    /* Table of contents */
    #WritelyTableOfContents a::after {
      content: leader('.') target-counter(attr(href), page);
    }

    #WritelyTableOfContents a {
      text-decoration: none;
      color: black;
    }
  }

  @page {
    @top {
      content: flow(header);
    }
    @bottom {
      content: flow(footer);
    }
    @footnotes {
      border-top: solid black thin;
      padding-top: 8pt;
    }
  }
  /* end default print css */


/* custom css */


/* end custom css */

/* ui edited css */

body {
  font-family: Verdana;
  
  font-size: 10.0pt;
  line-height: normal;
  background-color: #ffffff;
}
/* end ui edited css */


/* editor CSS */
.editor a:visited {color: #551A8B}
.editor table.zeroBorder {border: 1px dotted gray}
.editor table.zeroBorder td {border: 1px dotted gray}
.editor table.zeroBorder th {border: 1px dotted gray}


.editor div.google_header, .editor div.google_footer {
  border: 2px #DDDDDD dashed;
  position: static;
  width: 100%;
  min-height: 2em;
}

.editor .misspell {background-color: yellow}

.editor .writely-comment {
  font-size: 9pt;
  line-height: 1.4;
  padding: 1px;
  border: 1px dashed #C0C0C0
}


/* end editor CSS */

</style>

  
  <title>K25 - HF - SMM &amp; HF</title>

</head><body>
    
    
    
<div style="text-align: center;">
  <h1>
    Πληροφορική &amp; Τηλεπικοινωνίες K25<br>
    Ανάπτυξη Λογισμικού<br>
    Χειμερινό Εξάμηνο 2009-10<br>
    Καθηγητής Γιάννης Ιωαννίδης
  </h1>
</div>
<p>
</p>
<hr>
<h1 style="text-align: center;">
  Μέρος 2ο, 2/2: Μονάδα διαχείρισης σαρώσεων και Επίπεδο αρχείου εγγραφών<br>
</h1>
<div>
</div>
<h3 style="text-align: center;">
  (Ημερομηνία Παράδοσης: Τρίτη, 8/12/2009, 17:00)
</h3>
<br>
<br>
<div style="text-align: center;">
  <img src="SMM_HF_files/drawing_snTqL4lRg5wNfLcR_A-TMdA_158.png"><br>
</div>
<br>
<br>
<br>
<b><font size="4"><i>Μονάδα διαχείρισης σαρώσεων (Scan Management Module)</i></font></b><br>
<div style="text-align: left;">
  <hr size="2">
</div>
<h2 style="text-align: left;">
  Εισαγωγή
</h2>
Η μονάδα διαχείρισης σαρώσεων του επιπέδου διαχείρισης αρχείων σωρού
(HF) είναι υπεύθυνο για την αναζήτηση εγγραφών από ανοιχτά αρχεία, οι
οποίες ικανοποιούν ορισμένες συνθήκες. Περιλαμβάνει συναρτήσεις που
αφορούν τη δημιουργία μιας νέας αναζήτησης σε ένα αρχείο, την αναζήτηση
εγγραφών που ικανοποιούν τις συνθήκες, το κλείσιμο αναζητήσεων κ.λπ.<br>
<br>
Συγκεκριμένα, φροντίζει ώστε να ξεκινάει μία νέα αναζήτηση σε κάποιο
ανοιχτό αρχείο, με βάση ορισμένα κριτήρια τα οποία δίνονται εξ αρχής
και δεν διαφοροποιούνται κατά τη διάρκεια της αναζήτησης. Γίνεται
αναζήτηση μέσα στο αρχείο σωρού και επιστρέφονται οι εγγραφές που
ικανοποιούν το αντίστοιχο κριτήριο. Μπορείτε να θεωρήσετε ότι ανά πάσα
στιγμή υπάρχουν το πολύ MAXSCANS = 20 αναζητήσεις.<br>
<br>
Η εργασία αυτή είναι ομαδική. Η γλώσσα υλοποίησης είναι η C.<br>
<div style="text-align: left;">
  <br>
</div>
<hr>
<div style="text-align: left;">
  <font size="4"><b>Ρουτίνες Υλοποίησης της μονάδας διαχείρισης σαρώσεων&nbsp;</b></font>
</div>
<br>
<font size="4">SMM_Init();<br>
</font><br>
void SMM_Init(void);<br>
<br>
Η ρουτίνα αυτή χρησιμοποιείται για να αρχικοποιήσετε τις όποιες
καθολικές (global) εσωτερικές δομές δεδομένων αποφασίσετε ότι
χρειάζεστε να έχετε. Δεν έχει καμία παράμετρο εισόδου και δεν παράγει
καμία έξοδο.<br>
<br>
<br>
<font size="4">SMM_OpenFileScan();<br>
<br>
</font>int SMM_OpenFileScan(<br>
<font face="Courier New"> &nbsp;&nbsp; &nbsp;int fileDesc, &nbsp; /* αριθμός που αντιστοιχεί σε ανοιχτό αρχείο */<br>
&nbsp;&nbsp; &nbsp;int recordSize, /* μέγεθος κάθε εγγραφής του αρχείου */<br>
&nbsp;&nbsp; &nbsp;char attrType,&nbsp; /* τύπος πεδίου: 'c', 'i', ή 'f' */<br>
&nbsp;&nbsp; &nbsp;int attrLength, /* μέγεθος πεδίου σε μπάιτ: 4 για 'i' ή 'f', 1-255 για 'c' */<br>
&nbsp;&nbsp; &nbsp;int attrOffset, /* απόσταση πεδίου σε μπάιτ από την αρχή της εγγραφής */<br>
&nbsp;&nbsp; &nbsp;int op,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* τελεστής σύγκρισης */<br>
&nbsp;&nbsp; &nbsp;char *value&nbsp;&nbsp;&nbsp;&nbsp; /* δείκτης προς τιμή για σύγκριση */<br>
</font>);<br>
<br>
Η ρουτίνα αυτή ξεκινά μια σάρωση των εγγραφών του αρχείου με αναγνωριστικό αριθμό <i>fileDesc. </i>Η σάρωση αφορά εγγραφές που έχουν στο σημείο (πεδίο) που προσδιορίζεται από την τιμή <i>attrOffset</i> τιμές που ικανοποιούν την καθορισμένη συνθήκη. Το μέγεθος της εγγραφής είναι <i>recordSize</i>. Αν η παράμετρος <i>value</i> έχει μηδενικό δείκτη ως τιμή (null), τότε ξεκινά σάρωση όλων των εγγραφών ανεξαρτήτως των τιμών των παραμέτρων <i>attrType</i>, <i>attrLength</i>, <i>attrOffset</i>, και <i>op</i>. Ειδ' αλλοιώς, ο δείκτης <i>value</i> δείχνει στην τιμή με την οποία τα αντίστοιχα σημεία των εγγραφών πρέπει να συγκριθούν σύμφωνα με τον τελεστή <i>op</i>. Μια εγγραφή <i>record</i> ικανοποιεί τη συνθήκη της σάρωσης όταν <i>πεδίο(record) op value, </i>σύμφωνα με τα στοιχεία που δίνονται.<br>
Σε περίπτωση ορθής λειτουργίας επιστρέφεται από τη ρουτίνα ένας μη
αρνητικός ακέραιος που αντιπροσωπεύει το αναγνωριστικό της σάρωσης και
αντιστοιχεί στη θέση ενός πίνακα που θα διατηρείτε στη μνήμη με
πληροφορίες για όλες τις ενεργές σαρώσεις. Μπορείτε να υποθέσετε ότι
οποιαδήποτε στιγμή δεν θα υπάρχουν περισσότερες από <i>MAXSCANS</i>
= 20 ενεργές σαρώσεις. Αν ο πίνακας είναι γεμάτος, τότε η ρουτίνα
επιστρέφει κάποιον κωδικό σφάλματος του επιπέδου HF. Η παράμετρος <i>op</i> καθορίζει τον τρόπο με τον οποίο η τιμή που δείχνει ο δείκτης <i>value</i> πρέπει να συγκριθεί με τις προσδιορισμένες τιμές από τις εγγραφές. Οι διαφορετικές επιλογές για την τιμή της παραμέτρου <i>op</i> είναι οι εξής:<br>
<ol>
  <li>
    <font face="Courier New">για EQUAL (δηλαδή, attribute = value)</font>
  </li>
  <li>
    <font face="Courier New"> για LESS THAN (δηλαδή, attribute &lt; value)</font>
  </li>
  <li>
    <font face="Courier New"> για GREATER THAN (δηλαδή, attribute &gt; value)</font>
  </li>
  <li>
    <font face="Courier New"> για LESS THAN OR EQUAL (δηλαδή, attribute &lt;= value)</font>
  </li>
  <li>
    <font face="Courier New"> για GREATER THAN OR EQUAL (δηλαδή, attribute &gt;= value)</font>
  </li>
  <li>
    <font face="Courier New"> για NOT EQUAL (δηλαδή, attribute != value)</font>
  </li>
</ol>
<br>
<br>
<font size="4">SMM_FindNextRec();</font><br>
<br>
int SMM_FindNextRec(<br>
<font face="Courier New"> &nbsp;&nbsp; &nbsp;int scanDesc,&nbsp;&nbsp; /* αναγνωριστικός αριθμός που αντιστοιχεί σε ενεργή σάρωση */<br>
&nbsp;&nbsp; &nbsp;char *record&nbsp;&nbsp;&nbsp; /* δείκτης προς τα περιεχόμενα της εγγραφής που ζητήθηκε */<br>
);</font><br>
<br>
Η ρουτίνα αυτή ανακτά ένα αντίγραφο της επόμενης εγγραφής που συναντά κατά τη σάρωση με αναγνωριστικό σάρωσης <i>scanDesc</i> και που ικανοποιεί τη συνθήκη της σάρωσης. Αν πετύχει, τότε επιστρέφει το αντίστοιχο αναγνωριστικό εγγραφής (<i>recId</i>) ενώ τα περιεχόμενα της ίδιας της εγγραφής μπαίνουν (αντιγράφονται) στο χώρο που δείχνει ο δείκτης <i>record</i>.
Ειδ' αλλοιώς, η ρουτίνα επιστρέφει HFE_EOF εάν έχουμε φτάσει στο τέλος
του αρχείου, ή κάποιον άλλον κωδικό σφάλματος εάν κάτι δεν λειτουργήσει
όπως πρέπει.<br>
Παρατήρηση: Πληροφορίες όπως το αναγνωριστικό της εγγραφής που είχε
επιστρέψει η σάρωση την προηγούμενη φορά, το αρχείο που είναι ανοιχτό
λόγω αυτής της σάρωσης, κτλ., διατηρούνται στον πίνακα με τα
απαιτούμενα για κάθε ενεργή σάρωση. Εσείς θα αποφασίσετε τα ακριβή
περιεχόμενα του πίνακα αυτού σύμφωνα με τις ανάγκες της υλοποίησής σας.<br>
<br>
<br>
<font size="4">SMM_CloseFileScan();<br>
</font><br>
int SMM_CloseFileScan(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int scanDesc &nbsp; </span><font style="font-family: Courier New;" face="Courier New"> /* αριθμός που αντιστοιχεί σε ενεργή σάρωση */</font><br style="font-family: Courier New;">
);<font size="4"><br>
<br>
</font>Η ρουτίνα αυτή τερματίζει τη σάρωση με αναγνωριστικό σάρωσης <i>scanDesc</i>. Αν πετύχει, τότε επιστρέφει HFE_OK, ειδ' αλλοιώς, κάποιον κωδικό σφάλματος.<br>
<font size="4"><br>
SMM_hasOpenScans();</font><br>
<br>
BOOLEAN SMM_hasOpenScans(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int fileDesc&nbsp;&nbsp;&nbsp; </span><font style="font-family: Courier New;" face="Courier New"> /* αριθμός που αντιστοιχεί σε ανοιχτό αρχείο */</font><br style="font-family: Courier New;">
);<br>
<br>
Η ρουτίνα αυτή επιστρέφει TRUE αν το αρχείο με αναγνωριστικό fileDesc έχει ενεργές σαρώσεις<br>
ειδ' αλλοιώς FALSE.<br>
<br>
<br>
<h1 style="text-align: left;">
  <font size="4"><i>Επίπεδο αρχείου εγγραφών HF (Heap File)<br>
  </i></font>
</h1>
<div style="text-align: left;">
  <hr size="2">
</div>
<h2 style="text-align: left;">
  Εισαγωγή
</h2>
Το επίπεδο αρχείων σωρού παρέχει σε υψηλότερα επίπεδα μια διεπαφή προγραμματισμού για χρήση τέτοιου τύπου αρχείων (HF).<br>
Τα αρχεία σωρού είναι ένα επίπεδο υψηλότερα από τα αρχεία τύπου μπλοκ
(BF), γι' αυτό και χρησιμοποιούν τις συναρτήσεις του επιπέδου αυτού για
να πραγματοποιήσουν τη λειτουργικότητά τους. Η βασική τους
διαφοροποίηση είναι ότι τα HF αρχεία είναι υπεύθυνα για τη διαχείριση
εγγραφών, τόσο στο σύνολο του αρχείου όσο και σε κάθε block χωριστά.
Έτσι, το επίπεδο αυτό περιλαμβάνει συναρτήσεις που αφορούν την
εισαγωγή, διαγραφή και αναζήτηση εγγραφών βάσει συγκεκριμένων κριτηρίων.<br>
<br>
Το HF επίπεδο ενσωματώνει ουσιαστικά τη λειτουργικότητα του RMM (Record
Management Module) και του SMM (Scan Management Module) και είναι
υπεύθυνο ώστε να καλεί σωστά τις αντίστοιχες συναρτήσεις με τον τρόπο
που χρειάζεται. Συνεπώς, το μεγαλύτερο μέρος της λειτουργικότητας των
HF συναρτήσεων το έχετε ήδη υλοποιήσει από το RMM και το SMM τμήμα της
εργασίας αντίστοιχα.<br>
<br>
<div style="text-align: left;">
  <br>
  Η εργασία αυτή είναι ομαδική. Η γλώσσα υλοποίησης είναι η C.<br>
</div>
<div style="text-align: left;">
  <br>
</div>
<hr>
<div style="text-align: left;">
  <font size="4"><b>Ρουτίνες Υλοποίησης του επιπέδου HF</b></font>
</div>
<br>
<br>
<font size="4">void HF_Init(void);</font><br>
<br>
void HF_Init(void);<br>
<br>
Η συνάρτηση αυτή καλεί τις αντίστοιχες Init() συναρτήσεις του RMM και
SMM επιπέδου για να αρχικοποιήσει τις όποιες εσωτερικές καθολικές
(global) μεταβλητές χρησιμοποιούνται. Δεν δέχεται καμία παράμετρο ως
είσοδο και δεν παράγει καμία έξοδο.<br>
<br>
<br>
<font size="4">int HF_CreateFile()</font><br>
<br>
int HF_CreateFile(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;char *fileName /* όνομα αρχείου προς δημιουργία */</span><br>
)<br>
<br>
Η ρουτίνα αυτή δημιουργεί ένα HF αρχείο με όνομα filename,
χρησιμοποιώντας και τις συναρτήσεις του BF επιπέδου. Επιστρέφει HFE_OK
ή αντίστοιχο κωδικό σφάλματος αν κάτι δεν πάει καλά.<br>
<br>
<font size="4"><br>
int HF_DestroyFile()</font><br>
<br>
int HF_DestroyFile(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;char *fileName /* όνομα αρχείου προς διαγραφή */</span><br>
);<br>
<br>
Η ρουτίνα αυτή διαγράφει ένα HF αρχείο με όνομα filename,
χρησιμοποιώντας και τις συναρτήσεις του BF επιπέδου. Για τη διαγραφή
του αρχείου, δεν πρέπει να υπάρχουν ανοιχτές σαρώσεις σε αυτό.
Επιστρέφει HFE_OK ή αντίστοιχο κωδικό σφάλματος.<br>
<br>
<br>
<font size="4">int HF_OpenFile()</font><br>
<br>
int HF_OpenFile(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp;&nbsp; char *fileName /* όνομα αρχείου προς άνοιγμα */</span><br>
);<br>
<br>
Η ρουτίνα αυτή ανοίγει το HF αρχείο με όνομα filename χρησιμοποιώντας
συναρτήσεις του επιπέδου διαχείρισης αρχείων μπλοκ (BF). Επιστρέφει τον
αναγνωριστικό αριθμό αρχείου όπως αυτός δίνεται από το BF επίπεδο ή τον
αντίστοιχο κωδικό σφάλματος σε περίπτωση λάθους.<br>
<br>
<br>
<font size="4">int HF_CloseFile()</font><br>
<br>
int HF_CloseFile(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int fileDesc /* αναγνωριστικός αριθμός για το HF επίπεδο */</span><br style="font-family: Courier New;">
);<br>
<br>
Η ρουτίνα αυτή κλείνει το HF αρχείο με αναγνωριστικό αριθμό fileDesc,
καλώντας τις αντίστοιχες συναρτήσεις και του BF επιπέδου. Για το
κλείσιμο του αρχείου δεν πρέπει να υπάρχει ανοιχτή σάρωση που να το
αφορά. Επιστρέφει HFE_OK αν το αρχείο κλείσει κανονικά ή αντίστοιχο
κωδικό σφάλματος.<br>
<br>
<br>
<font size="4">int HF_InsertRec()</font><br>
<br>
int HF_InsertRec(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int fileDesc, /* αναγνωριστικός αριθμός ανοιχτού αρχείου */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;char *record, /* ενδιάμεση μνήμη εγγραφής προς εισαγωγή */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int recordSize /* μέγεθος της εγγραφής στο αρχείο */</span><br style="font-family: Courier New;">
);<br>
<br>
Εισάγει στο ανοικτό αρχείο με αναγνωριστικό αριθμό fileDesc ένα
αντίγραφο της εγγραφής που είναι αποθηκευμένη στην ενδιάμεση μνήμη
record. Η εγγραφή αυτή έχει μέγεθος recordSize, όπως και κάθε άλλη
εγγραφή του αρχείου αυτού. Η εγγραφή αποθηκεύεται στην πρώτη θέση που
υπάρχει διαθέσιμη μέσα στο αρχείο. Επιστρέφεται ένας μη αρνητικός
ακέραιος που δηλώνει τη θέση όπου τοποθετήθηκε η συγκεκριμένη εγγραφή
και είναι ο αναγνωριστικός αριθμός εγγραφής. Σε περίπτωση σφάλματος
επιστρέφεται ο αντίστοιχος κωδικός λάθους.<br>
<br>
<br>
<font size="4">int HF_DeleteRec()</font><br>
<br>
int HF_DeleteRec(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int fileDesc, /* αναγνωριστικός αριθμός ανοιχτού αρχείου */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int recId, /* αναγνωριστικός αριθμός εγγραφής */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int recordSize /* μέγεθος της εγγραφής στο αρχείο */</span><br>
);<br>
<br>
Η ρουτίνα αυτή διαγράφει από το ανοιχτό αρχείο με αναγνωριστικό αριθμό
fileDesc την εγγραφή με αναγνωριστικό αριθμό recId. Κάθε εγγραφή στο
αρχείο έχει μέγεθος recordSize. Η εγγραφή πρέπει να υπάρχει προκειμένου
να διαγραφεί.<br>
<br>
<br>
<font size="4">int HF_GetFirstRec()</font><br>
<br>
int HF_GetFirstRec(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int fileDesc, /* αναγνωριστικός αριθμός ανοιχτού αρχείου */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;char *record, /* ενδιάμεση μνήμη εγγραφής προς ανάγνωση */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int recordSize /* μέγεθος της εγγραφής στο αρχείο */</span><br style="font-family: Courier New;">
);<br>
<br>
Η ρουτίνα αυτή διαβάζει την πρώτη έγκυρη εγγραφή που υπάρχει στο
ανοιχτό αρχείο με αναγνωριστικό αριθμό fileDesc. Κάθε εγγραφή του
αρχείου έχει μέγεθος recordSize, ενώ η εγγραφή αντιγράφεται στην
ενδιάμεση μνήμη record που δίνεται ως παράμετρος. Η συνάρτηση
επιστρέφει ένα θετικό ακέραιο που αντιστοιχεί στον αναγνωριστικό αριθμό
εγγραφής του επιπέδου HF ή κάποιο κωδικό σφάλματος του HF επιπέδου σε
περίπτωση λάθους.<br>
<br>
<br>
<font size="4">int HF_GetNextRec()</font><br>
<br>
int HF_GetNextRec(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp;&nbsp; int fileDesc, /* αναγνωριστικός αριθμός ανοιχτού αρχείου */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp;&nbsp; int recId, /* αναγνωριστικός αριθμός εγγραφής */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp;&nbsp; </span><span style="font-family: Courier New;">char *record, /* ενδιάμεση μνήμη εγγραφής προς ανάγνωση */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp;&nbsp; </span><span style="font-family: Courier New;">int recordSize /* μέγεθος της εγγραφής στο αρχείο */</span><br style="font-family: Courier New;">
);<br>
<br>
<font size="4"><font size="2">Η </font></font><font size="4"><font size="2">ρουτίνα </font></font><font size="4"><font size="2"> αυτή διαβάζει στην ενδιάμεση μνήμη <i>record</i> την πρώτη έγκυρη εγγραφή μετά την εγγραφή με αναγνωριστικό <i>recId</i> που αφορά στο ανοιχτό αρχείο με αναγνωριστικό αριθμό (ανοίγματος) <i>fileDesc</i>. Κάθε εγγραφή στο αρχείο αυτό έχει μέγεθος <i>recordSize</i>. Δεν πραγματοποιείται κανένας έλεγχος για την εγκυρότητα του <i>recId</i>.<br>
Η ρουτίνα επιστρέφει ένα θετικό ακέραιο που αντιστοιχεί στον
αναγνωριστικό αριθμό της εγγραφής που μόλις διαβάστηκε αν όλα πήγαν
καλά ή κάποιο κωδικό σφάλματος του HF επιπέδου σε περίπτωση λάθους.<br>
<br>
</font><br>
int HF_GetThisRec()</font><br>
<br>
int HF_GetThisRec(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp;&nbsp; int fileDesc, /* αναγνωριστικός αριθμός ανοιχτού αρχείου */</span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp;&nbsp; int recId, /* αναγνωριστικός αριθμός εγγραφής */</span><span style="font-family: Courier New;"><br>
&nbsp;&nbsp; &nbsp;char *record, /* ενδιάμεση μνήμη εγγραφής προς ανάγνωση */<br>
&nbsp;&nbsp;&nbsp; </span><span style="font-family: Courier New;">int recordSize /* μέγεθος της εγγραφής στο αρχείο */</span><br style="font-family: Courier New;">
);<br>
<br>
Η ρουτίνα αυτή διαβάζει στην ενδιάμεση μνήμη <i>record </i>την εγγραφή με αναγνωριστικό αριθμό εγγραφής <i>recId</i> από το ανοιχτό αρχείο με αναγνωριστικό αριθμό (ανοίγματος) fileDesc. Κάθε εγγραφή στο αρχείο έχει μέγεθος recordSize.<br>
Η συνάρτηση επιστρέφει HFE_OK αν όλα πήγαν καλά ή κάποιο κωδικό σφάλματος σε περίπτωση λάθους.<br>
<br>
<font size="4"><br>
int HF_OpenFileScan()</font><br>
<br>
int HF_OpenFileScan(<br>
<font face="Courier New"> &nbsp;&nbsp;&nbsp; int fileDesc, &nbsp; /* αριθμός που αντιστοιχεί σε ανοιχτό αρχείο */<br>
&nbsp;&nbsp; &nbsp;int recordSize, /* μέγεθος κάθε εγγραφής του αρχείου */<br>
&nbsp;&nbsp; &nbsp;char attrType,&nbsp; /* τύπος πεδίου: 'c', 'i', ή 'f' */<br>
&nbsp;&nbsp; &nbsp;int attrLength, /* μέγεθος πεδίου σε μπάιτ: 4 για 'i' ή 'f', 1-255 για 'c' */<br>
&nbsp;&nbsp; &nbsp;int attrOffset, /* απόσταση πεδίου σε μπάιτ από την αρχή της εγγραφής */<br>
&nbsp;&nbsp; &nbsp;int op,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* τελεστής σύγκρισης */<br>
&nbsp;&nbsp; &nbsp;char *value&nbsp;&nbsp;&nbsp;&nbsp; /* δείκτης προς τιμή για σύγκριση */</font><br>
);<br>
<br>
Η ρουτίνα αυτή ανοίγει μια σάρωση εγγραφών στο ανοιχτό αρχείο με αναγνωριστικό αριθμό (ανοίγματος) <i>fileDesc</i>. Κάθε εγγραφή στο αρχείο έχει μέγεθος <i>recordSize</i>. Η σάρωση που πραγματοποιείται, ψάχνει για εγγραφές στο HF αρχείο οι οποίες ικανοποιούν τη συνθήκη που ορίζεται από τα πεδία <i>attrType, attrLength, attrOffset, op</i> και <i>value.</i><br>
Ο τρόπος με τον οποίο οι παράμετροι αυτές χρησιμοποιούνται είναι
πανομοιότυπος με αυτόν της SMM_OpenFileScan(). Για το λόγο αυτό
ανατρέξτε στην αντίστοιχη ρουτίνα για να δείτε οι πληροφορίες αυτές
χρησιμοποιούνται.<br>
Η συνάρτηση επιστρέφει έναν μικρό θετικό ακέραιο που πρόκειται για τον
αναγνωριστικό αριθμό της ανοιχτής σάρωσης αν όλα πήγαν καλά, ενώ
επιστρέφει τον αντίστοιχο κωδικό σφάλματος του HF επιπέδου σε περίπτωση
λάθους.<br>
<br>
<font size="4"><br>
int HF_FindNextRec()</font><br>
<br>
int HF_FindNextRec(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int scanDesc, /* αναγνωριστικός αριθμός ανοιχτής σάρωσης */ </span><br style="font-family: Courier New;">
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;char *record /* ενδιάμεση μνήμη για την εγγραφή */</span><br style="font-family: Courier New;">
);<br>
<br>
Η ρουτίνα αυτή επιστρέφει την επόμενη εγγραφή που ικανοποιεί τα κριτήρια της ανοιχτής σάρωσης με αναγνωριστικό αριθμό <i>scanDesc</i>. Η εγγραφή αποθηκεύεται στην ενδιάμεση μνήμη <i>record</i> που δίνεται ως όρισμα. Η συνάρτηση επιστρέφει τον αναγνωριστικό αριθμό εγγραφής <i>recId </i>της
εγγραφής που ικανοποιεί την συνθήκη της ανοιχτής σάρωσης σε περίπτωση
που όλα πάνε καλά, διαφορετικά επιστρέφει τον αντίστοιχο κωδικό
σφάλματος HF επιπέδου σε περίπτωση σφάλματος.<br>
<font size="4"><br>
<br>
int HF_CloseFileScan()</font><br>
<br>
int HF_CloseFileScan(<br>
<span style="font-family: Courier New;">&nbsp;&nbsp; &nbsp;int scanDesc /* αναγνωριστικός αριθμός ανοιχτής σάρωσης */</span><br style="font-family: Courier New;">
);<br>
<br>
Η ρουτίνα αυτή κλείνει την ανοιχτή σάρωση με αναγνωριστικό αριθμό <i>scanDesc</i>.
Για το σκοπό αυτό χρησιμοποιεί την αντίστοιχη συνάρτηση του SMM
επιπέδου. Η συνάρτηση επιστρέφει HFE_OK αν όλα πήγαν καλά ενώ
επιστρέφει τον αντίστοιχο κωδικό σφάλματος σε περίπτωση λάθους.<br>
<br>
<h3>
  HF_PrintError()
</h3>
<font face="Courier New"><span style="font-family: Verdana;">void HF_PrintError</span>(<br>
&nbsp;&nbsp; &nbsp;char *errString /* κείμενο για εκτύπωση */<br>
);</font><br>
<br>
Η ρουτίνα τυπώνει το κείμενο που δείχνει η παράμετρος <i>errString</i>,
και μετά τυπώνει το μήνυμα που αντιστοιχεί στο τελευταίο σφάλμα που
προέκυψε από οποιαδήποτε από τις ρουτίνες του επιπέδου HF. Για τον
σκοπό αυτό, η ρουτίνα αυτή χρησιμοποιεί μία καθολική (global) μεταβλητή
<i>HF_errno</i> η οποία αποθηκεύει πάντα τον κωδικό του πλέον πρόσφατου
σφάλματος. Ο κωδικός αυτός σφάλματος πρέπει πάντα να ενημερώνεται σωστά
σε όλες τις άλλες ρουτίνες. Η ρουτίνα αυτή δεν έχει δική της τιμή
επιστροφής.<br>
<br>
<br>
<h2>
  <img src="SMM_HF_files/MISSING.html"> Σχολιασμός, Έλεγχος Σφαλμάτων, και Γενική Μορφοποίηση
</h2>
Όπως πάντοτε, αναμένεται καλός σχολιασμός του προγράμματος, και
εσωτερικός (ανάμεσα στις γραμμές κώδικα) και εξωτερικός (στην αρχή κάθε
ρουτίνας). Ένας γενικός κανόνας είναι να σχολιάζετε τα προγράμματά σας
σαν να πρόκειται να τα δώσετε σε κάποιον άλλον ο οποίος θα τα
επεκτείνει και ο οποίος δεν έχει ιδέα για το τι κάνατε όταν τα γράφατε
(και δεν μπορεί ούτε να σας βρει να σας ρωτήσει).
<p> Επίσης, θα πρέπει να ελέγχετε για διάφορα σφάλματα που μπορούν να
προκύψουν και να βεβαιωθείτε ότι ο κώδικάς σας τερματίζει ομαλά, με
μηνύματα που έχουν νόημα, σε όλες τις εισόδους που ικανοποιούν την
παραπάνω περιγραφή.
</p>
<hr>
<h2>
  <img src="SMM_HF_files/MISSING.html">Διαδικαστικές Λεπτομέρειες
</h2>Το τί ακριβώς θα παραδώσετε, πού θα βρείτε τα αρχεία με τα οποία
θα ελέγξετε τελικά το πρόγραμμά σας, κτλ., θα ανακοινωθεί σύντομα.
<p> Τα προγράμματά σας θα πρέπει να δουλεύουν στα μηχανήματα του
τμήματος (είτε στα sun (Linux) είτε στα pc (Windows)) ώστε να μπορούν
να ελεγχθούν. Ακόμη και αν δουλέψετε σε δικούς σας υπολογιστές θα
πρέπει να βεβαιωθείτε ότι το τελικό αποτέλεσμα δουλεύει και εδώ τοπικά.
Η έκδοση της C που θα χρησιμοποιήσετε πρέπει να έχει ακέραιους των 4
bytes και να επιτρέπει αλλαγή ερμηνείας τύπου δεδομένων (type casting).
</p>
<hr size="2"><br>
<br></body></html>